package org.fanximall.erp.common.result;

import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;
import org.fanximall.erp.common.constant.WebConstants;
import org.fanximall.erp.common.errorcode.BaseErrorCode;
import org.fanximall.erp.common.exception.AbstractException;
import org.slf4j.MDC;

import java.util.Optional;

/**
 * @author :  william
 * @version :  V1.0  created in 2024/4/19
 * web返回对象
 */
@Getter
@Setter
@Accessors(chain = true)
public class Result<T> {


    private static final long serialVersionUID = 5679018624309023727L;

    /**
     * 正确返回码
     */
    public static final String SUCCESS_CODE = "0";

    /**
     * 返回码
     */
    private String code;

    /**
     * 返回消息
     */
    private String message;

    /**
     * 响应数据
     */
    private T data;

    /**
     * 请求ID
     */
    private String requestId;


    public boolean isSuccess() {
        return SUCCESS_CODE.equals(code);
    }


    /**
     * 构造成功响应
     *
     * @return
     */
    public static Result<Void> success() {
        return new Result<Void>()
                .setCode(Result.SUCCESS_CODE)
                .setRequestId(MDC.get(WebConstants.TRACE_ID));
    }

    /**
     * 构造带返回数据的成功响应
     *
     * @param data
     * @param <T>
     * @return
     */
    public static <T> Result<T> success(T data) {
        return new Result<T>()
                .setCode(Result.SUCCESS_CODE)
                .setRequestId(WebConstants.TRACE_ID)
                .setData(data);
    }

    /**
     * 构建服务端失败响应
     *
     * @return
     */
    protected static Result<Void> failure() {
        return new Result<Void>()
                .setCode(BaseErrorCode.SERVICE_ERROR.code())
                .setRequestId(WebConstants.TRACE_ID)
                .setMessage(BaseErrorCode.SERVICE_ERROR.message());
    }

    /**
     * 通过 {@link AbstractException} 构建失败响应
     *
     * @param abstractException
     * @return
     */
    protected static Result<Void> failure(AbstractException abstractException) {
        String errorCode = Optional.ofNullable(abstractException.getErrorCode())
                .orElse(BaseErrorCode.SERVICE_ERROR.code());
        String errorMessage = Optional.ofNullable(abstractException.getErrorMessage())
                .orElse(BaseErrorCode.SERVICE_ERROR.message());
        return new Result<Void>()
                .setCode(errorCode)
                .setRequestId(WebConstants.TRACE_ID)
                .setMessage(errorMessage);
    }

    /**
     * 通过 errorCode、errorMessage 构建失败响应
     *
     * @param errorCode
     * @param errorMessage
     * @return
     */
    protected static Result<Void> failure(String errorCode, String errorMessage) {
        return new Result<Void>()
                .setCode(errorCode)
                .setRequestId(WebConstants.TRACE_ID)
                .setMessage(errorMessage);
    }
}
